#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
/*
void worker(int cnt)
{
    printf("i am child ,pid= %d, cnt= %d\n",getpid(),cnt);
}
int main()
{


   pid_t id=fork();//创建一个子进程
   if(id==0)//子进程返回值
   {
       int cnt=5;
       while(cnt)
       {
           worker(cnt);
           sleep(2); //如果程序执行过快，那么监视窗口容易监视不到
           cnt--;
       }

       exit(0);//直接退出子进程
   }

   //走到这一步的一定是父进程了
   while(1) //循环来实现父进程的非阻塞轮询等待
   {
         int status=0;
         pid_t rid=waitpid(id,&status,WNOHANG);//以非阻塞的方式等待
   
         if(rid>0)//等待成功，且子进程退出
         {
       // printf("wait success ,child exit now\n");
             printf("exit code =%d. exit signal =%d\n",(status>>8)&0xFF,status&0x7F);//分别取出进程的退出码额退出信号
             break;
         }
         else if(rid==0)//等待子进程成功，但是子进程还没有退出，也就是非阻塞等待
         {
                printf("do else things\n");
         }
         else //进程退出失败
         {
               break;
         }
         sleep(1);//等待一段时间，否则循环速度太快
   }
    return 0;
}
*/


int main()
{
    pid_t id=fork();//创建子进程
    char* const argv[]={"ls","-a","-l",NULL};
    if(id==0)//子进程
    {
         printf("process pid before =%d\n",getpid());//程序替换之前进程的pid
         // execl("/usr/bin/ls","ls","-a","-l",NULL);//程序替换为ls命令，其本质也是一个可执行程序
         //execlp("ls","ls","-a","-l",NULL);//通过环境变量寻找可执行程序
         //execv("/usr/bin/ls",argv);//通过给定数组的方式指定命令行参数
         //execvp("ls",argv); //通过数组和环境变量的方式
         //execl("./testc++","testc++",NULL);//通过相对路径进行调用
         //execl("/usr/bin/python3","python3","testpython3.py",NULL);//通过调用python解释器来实现
         execl("/usr/bin/bash","bash","testshell.sh",NULL);
         printf("process pid behind =%d\n",getpid());
    }

    else //父进程
    {
      //如果父进程能够等待到子进程，那么就说明子进程的pid没有改变，也相当于程序替换没有创建新的进程
      pid_t rid=waitpid(id,NULL,0);

      if(rid>0)//说明父进程等待成功,rid就是子进程的pid
      {
          printf("waie success ,child pid=%d\n",rid);

      }
    }
    return 0;
}
